package de.westranger.forex.v2.normalize;

public final class Normalize {

	public static double[] zeroMean(final double[] data) {
		final double mean = mean(data);
		double[] result = new double[data.length];
		for (int i = 0; i < data.length; i++) {
			result[i] = data[i] - mean;
		}
		return result;
	}

	public static double[] unitVariance(final double[] data) {
		final double stddev = stddev(data);
		double[] result = new double[data.length];
		for (int i = 0; i < data.length; i++) {
			result[i] = data[i] / stddev;
		}
		return result;
	}

	public static double[] scale(final double[] data, final double minValue, final double maxValue) {
		double[] result = new double[data.length];
		double min = Double.MAX_VALUE;
		double max = Double.MIN_VALUE;

		for (int i = 0; i < data.length; i++) {
			min = Math.min(min, data[i]);
			max = Math.max(max, data[i]);
		}

		final double diff = max - min;
		final double diffNew = maxValue - minValue;

		for (int i = 0; i < data.length; i++) {
			result[i] = data[i] - min;
			result[i] /= diff;
			result[i] *= diffNew;
			result[i] += minValue;
		}
		return result;
	}

	public static double mean(final double[] data) {
		double result = 0;
		for (double d : data) {
			result += d;
		}
		return result / data.length;
	}

	public static double variance(final double[] data) {
		final double mean = mean(data);
		double result = 0;
		for (double d : data) {
			result += (mean - d) * (mean - d);
		}
		return result / (data.length-1.0);
	}

	public static double stddev(final double[] data) {
		return Math.sqrt(variance(data));
	}
}
